package com.kitty.game.activity.service.shidao;

import com.kitty.common.db.Db4CommonService;
import com.kitty.common.thread.IdGenerator;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.ServerService;
import com.kitty.game.activity.ActivityDataPool;
import com.kitty.game.activity.message.RespOpenShiDaoWZDLG;
import com.kitty.game.activity.message.vo.ShiDaoMemberInfo;
import com.kitty.game.activity.model.product.ShiDaoReward;
import com.kitty.game.activity.model.user.ShiDaoData;
import com.kitty.game.activity.model.user.ShiDaoGloryHistory;
import com.kitty.game.activity.model.user.ShiDaoGloryRecord;
import com.kitty.game.activity.model.user.ShiDaoPKData;
import com.kitty.game.activity.service.ActivityHandler;
import com.kitty.game.boss.service.NewBossService;
import com.kitty.game.config.TaskSet;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.fight.bean.Fight;
import com.kitty.game.fight.factory.FightFactory;
import com.kitty.game.fight.service.FightService;
import com.kitty.game.fight.service.OneThreadService;
import com.kitty.game.role.model.Role;
import com.kitty.game.task.model.product.TaskType;
import com.kitty.game.task.service.taskHandler.TaskHelper;
import com.kitty.game.team.model.Member;
import com.kitty.game.team.model.Team;
import com.kitty.game.team.service.TeamService;
import com.kitty.game.utils.Const;
import com.kitty.game.utils.JsonUtils;
import com.kitty.game.utils.TimeUtil;
import com.kitty.game.welfare.model.CommonFetchedData;
import com.kitty.listener.event.FightEndEvent;
import com.kitty.mina.cache.DataCache;
import com.kitty.mina.cache.SessionUtils;
import com.kitty.mina.task.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.mina.core.session.IoSession;
import org.nutz.dao.Dao;
import org.nutz.http.Request;
import org.nutz.http.Sender;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.util.NutMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**试道大会PK阶段处理类*/
@Component
@Slf4j
public class ShiDaoPKHandler extends ActivityHandler {
    @Autowired
    protected TeamService teamService;
    @Autowired
    protected NewBossService bossService;
    @Autowired
    protected FightService fightService;
    @Autowired
    ShiDaoHandler shiDaoHandler;
    @Autowired
    ServerService serverService;

    /**胜利获得的试道积分*/
    private static final byte SCORE_WIN = 5;
    /**检测间隔*/
    private static final long CHECK_INTERVAL = 10 * TimeUtil.ONE_SECOND;
    /**PK间隔*/
    private static final long PK_INTERVAL = 5 * TimeUtil.ONE_SECOND;

    private ScheduledFuture scheduledFuture;

    /**最大回合数*/
    private static final byte MAX_ROUND = 20;

    /**取排名数量*/
    private static final byte TOP_COUNT = 3;

    private static final String WIN_MESSAGE = "恭喜你取得了战斗胜利，获得了{0}点试道积分，你当前的试道积分为#R{1}#n点。";
    private static final String FAIL_MESSAGE = "真遗憾你失败了，失去了1点巅峰对决值。";
    private static final String OUT_MESSAGE = " 真是精彩纷呈啊！#Y{0}#n级别的试道大会正在如火如荼的进行！适才#Y{1}#n在高手对决中棋差一着，遗憾地败下阵来，真是太可惜了。其他还在试道场内拼搏的高手要继续努力！";
    private static final String REMAIN_TIME_MESSAGE = "#Y{0}#n级别的试道大会还剩#R{1}分钟#n，大家要抓紧时间啦！";
    private static final String USED_TIME_MESSAGE = "#Y{0}#n级别的试道大会已经进行了#R{1}分钟#n，大家加油啊！";
    private static final String FIRST_MESSAGE = "恭喜，#Y{0}#n获得了本届#Y{1}#n级别的试道大会的#R第一名#n。";


    /**试道PK阶段开始*/
    public void start() {
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        shiDaoData.setStage(ShiDaoData.STAGE_PK);

        /**更新为开始PK进度*/
        Set<String> levelRanges = shiDaoData.getPkDataByLevel().keySet();
        for (String levelRange : levelRanges) {
            List<ShiDaoPKData> shiDaoPKDataList = shiDaoData.getPkDataByLevel().get(levelRange);
            for (ShiDaoPKData shiDaoPKData : shiDaoPKDataList) {
                Team team = teamService.getTeamByTeamId(shiDaoPKData.getTeamId());
                if (team == null) {continue;}
                teamService.memberHandle(team, memberRole -> shiDaoHandler.sendRespShidaoScore(memberRole));
            }
        }

        log.info("试道大会巅峰对决开始");
        serverService.getScheduledExecutorService().schedule(new Runnable() {
            @Override
            public void run() {
                check();
            }
        },10,TimeUnit.SECONDS);
//        scheduledFuture = SchedulerManager.getInstance().scheduleAtFixedRate(new Runnable() {
//            @Override
//            public void run() {
//                check();
//            }
//        }, 20000, 20000);
    }


    /**定时检测，判断是否已经结束，或者匹配战斗*/
    private void check() {
        /**各等级段分别判断*/
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        if (shiDaoData == null || shiDaoData.getEndTime().getTimeInMillis() < System.currentTimeMillis()){
            log.error("试道结束，不在匹配");
            return;
        }
        try {
            Set<String> levelRanges = shiDaoData.getPkDataByLevel().keySet();
            log.error("试道pk匹配==={}", Json.toJson(levelRanges, JsonFormat.compact()));
            for (String levelRange : levelRanges) {
                log.error("试道pk匹配==={}", levelRange);
                if (isCanEnd(levelRange)) {
                    log.error("试道pk结束等级==={}",levelRange);
                    end(levelRange);
                } else {
                    log.error("试道pk匹配等级==={}",levelRange);
                    match(levelRange);

                    setRank(levelRange);
                }
            }
        }catch (Exception e){
            log.error("试道匹配出错",e);
        }
        serverService.getScheduledExecutorService().schedule(new Runnable() {
            @Override
            public void run() {
                check();
            }
        },10,TimeUnit.SECONDS);
    }

    /**是否可以结束*/
    private boolean isCanEnd(String levelRange) {
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        List<ShiDaoPKData> shiDaoPKData = shiDaoData.getPkDataByLevel().get(levelRange);
        List<Integer> list = shiDaoData.getFailTeamIds().get(levelRange);
        int failCount = list != null ? list.size() : 0;
        /**已经决出第一名*/
//        if (shiDaoPKData.size() <= failCount + 1) {
//            return true;
//        }

        /**还在试道场的队伍数量*/
        int remainTeamCount = 0;
        for (ShiDaoPKData data : shiDaoPKData) {
            if (data == null) {continue;}
            Team team = teamService.getTeamByTeamId(data.getTeamId());
            if (team == null) {continue;}
            Role leader = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
            if (leader == null) {continue;}
            if (shiDaoHandler.isInShiDaoMap(leader)) {
                remainTeamCount += 1;
            }
        }

        /**只剩1个队伍或者没有队伍时，可以结束*/
        if (remainTeamCount <= 1) {
            return true;
        }

        /**判断当时时间已到结束时间*/
        if (Calendar.getInstance().after(shiDaoData.getEndTime())) {
            return true;
        }
        return false;
    }

    public void end() {
        /**各等级段分别判断*/
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        Set<String> levelRanges = shiDaoData.getPkDataByLevel().keySet();
        for (String levelRange : levelRanges) {
            end(levelRange);
        }
//        shiDaoHandler.setShiDaoData(null);
        if (scheduledFuture != null) {
            scheduledFuture.cancel(Boolean.FALSE);
        }
    }

    /**结束*/
    public void end(String levelRange) {
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        if (shiDaoData.getEndLevelRanges().contains(levelRange)) {
            return ;
        }
        log.info("试道大会{}级别巅峰对决结束", levelRange);

        shiDaoData.getEndLevelRanges().add(levelRange);
        List<ShiDaoPKData> shiDaoPKDataList = shiDaoData.getPkDataByLevel().get(levelRange);
        List<Integer> list = shiDaoData.getFailTeamIds().get(levelRange);
        int failCount = list != null ? list.size() : 0;


        /**只剩1个队伍在场时,那个队伍则是第一名，后两名，则取积分排名前二名*/
        /**否则按积分排名，取前三名*/
        List<ShiDaoPKData> topList = new ArrayList<>(TOP_COUNT);
        if (shiDaoPKDataList.size() == failCount + 1) {
            for (ShiDaoPKData shiDaoPKData : shiDaoPKDataList) {
                Team temp = teamService.getTeamByTeamId(shiDaoPKData.getTeamId());
                if (temp == null){
                    continue;
                }
                boolean boo = false;
                for (Member member :temp.getList()){
                    if (shiDaoData.getRolesLeave().contains(member.getRoleId())){
                        boo = true;
                        break;
                    }
                    IoSession session = SessionUtils.getSession(member.getRoleId());
                    if (session == null){
                        boo = true;
                        break;
                    }
                    Role tempRole = SessionUtils.getRoleBySession(session);
                    if (tempRole == null){
                        boo = true;
                        break;
                    }
                }
                if (boo){
                    continue;
                }
                if (list != null && !list.contains(shiDaoPKData.getTeamId())) {
                    topList.add(shiDaoPKData);
                    break;
                }
            }
        }

        Collections.sort(shiDaoPKDataList);
        for (ShiDaoPKData shiDaoPKData : shiDaoPKDataList) {
            if (!topList.contains(shiDaoPKData)) {
                topList.add(shiDaoPKData);
            }

            if (topList.size() == TOP_COUNT) {break;}
        }

        /**在开始报名时已经回收过一次，再次回收是避免未执行开始报名时的逻辑*/
        shiDaoHandler.takeBackTitle(levelRange);
        shiDaoHandler.clearTopRecords(levelRange);

        acceptRewardTask(topList);//试道完毕领取任

        addGloryHistory(levelRange, topList.get(0));
        saveMonthTimes();
        showGlory(levelRange, topList.get(0));

        shiDaoHandler.addTitle(levelRange, topList);

        log.info("试道大会结束时，总pk队伍数量:{}，失败队伍数量:{}, 各队伍积分情况:{}，失败队伍列表:{}，前三名:{}", shiDaoPKDataList.size(), failCount,
                (shiDaoPKDataList != null ? JsonUtils.object2String(shiDaoPKDataList) : ""),
                (list != null ? JsonUtils.object2String(list) : ""),
                (topList != null ? JsonUtils.object2String(topList) : "")
        );
        log.info("试道大会结束时，队伍前三名=={}=={}",levelRange,(topList != null ? JsonUtils.object2String(topList) : ""));

        /**结束时，所有人离开*/
        for (ShiDaoPKData shiDaoPKData : shiDaoPKDataList) {
            Team team = SpringUtils.getTeamService().getTeamByTeamId(shiDaoPKData.getTeamId());
            if (team == null) {continue;}
            Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
            if (leaderRole == null) {continue;}
            shiDaoHandler.leaveShiDaoMap(leaderRole);
        }
    }

    /**接取领奖任务*/
    private void acceptRewardTask(List<ShiDaoPKData> topList) {
        for (int i=0, size = topList.size(); i < size; i++) {
            ShiDaoPKData shiDaoPKData = topList.get(i);

            byte rank = (byte) (i + 1);
            ShiDaoReward shiDaoReward = ActivityDataPool.shiDaoRewardMap.get(rank);
            if (shiDaoReward == null) {continue;}

            for (Member member : shiDaoPKData.getMembers()) {
                Role role = SpringUtils.getPlayerService().getPlayerBy(Long.parseLong(member.getGid()));
                StringBuilder shidaoRank = new StringBuilder();
                shidaoRank.append(shiDaoHandler.getShiDaoData().getStartTime().getTimeInMillis()).append("|").append(member.getLevel()).append("|").append(rank);
                role.getExtendBox().setShidaoRank(shidaoRank.toString());
                role.save();

//                TaskSet taskSet = SpringUtils.getTaskService().getTaskSet(ShiDaoHandler.REWARD_TASKID, role);//试道完毕领取任务
//                TaskHelper.INSTANCE.getTaskHandler(TaskType.SHIDAO).acceptTask(role, taskSet);//试道完毕领取任务
            }
        }
    }

    /**添加到试道王者榜*/
    private void addGloryHistory(String levelRange, ShiDaoPKData shiDaoPKData) {
        if (shiDaoPKData == null) {return ;}

        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        short level = Short.parseShort(levelRange.split("-")[0]);
        Map<Integer, List<ShiDaoGloryRecord>> map = DataCache.SHI_DAO_GLORY_HISTORYS.computeIfAbsent(level, k -> new ConcurrentHashMap<>());
        int time = (int)(shiDaoData.getEndTime().getTimeInMillis() / TimeUtil.ONE_SECOND);
        List<ShiDaoGloryRecord> records = new ArrayList<>();
        map.put(time, records);

        int leaderIndex = 0;
        for (int i = 0; i< shiDaoPKData.getMembers().size(); i++) {
            Member member = shiDaoPKData.getMembers().get(i);
            boolean isLeader = (i == leaderIndex ? true : false);
            records.add(new ShiDaoGloryRecord(member.getGid(), member.getName(), member.getLevel(), member.getIcon(), (byte) member.getMenpai(), isLeader));
        }

        /**保存入库*/
        Db4CommonService.getInstance().add2Queue(new ShiDaoGloryHistory(IdGenerator.getNextId(), level, time, records));
    }

    /**保存月试道大会时间*/
    private void saveMonthTimes() {
        Dao dao = SpringUtils.getBean(Dao.class);
        String data = JsonUtils.object2String(DataCache.MONTH_SHI_DAO_TIMES);
        dao.insertOrUpdate(new CommonFetchedData("month_shidao_times", data));
    }

    /**显示王者信息*/
    public void showGlory(String levelRange, ShiDaoPKData shiDaoPKData) {
        if (shiDaoPKData == null) {return ;}

        Team team = teamService.getTeamByTeamId(shiDaoPKData.getTeamId());
        if (team == null) {
            return ;
        }
        RespOpenShiDaoWZDLG respOpenShiDaoWZDLG = new RespOpenShiDaoWZDLG();
        List<ShiDaoMemberInfo> list = new ArrayList<>();
        respOpenShiDaoWZDLG.setList(list);
        teamService.memberHandle(team, (memberRole) -> {
            ShiDaoMemberInfo shiDaoMemberInfo = new ShiDaoMemberInfo(memberRole.getGid(), memberRole.getName(), memberRole.getLevel(), (byte) memberRole.getPolar(), memberRole.getRoleIcon());
            list.add(shiDaoMemberInfo);
        });

        teamService.pushMessageToTeam(team, respOpenShiDaoWZDLG);

        String names = teamService.checkMember(team, (memberRole) -> memberRole != null);
        String msg = MessageFormat.format(FIRST_MESSAGE, names, levelRange);
        SpringUtils.getChatService().sendSystem(msg, Const.BRODCAST_MSG_TYPE_ROLE);
    }

    /**匹配对手*/
    private void match(String levelRange) {
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        List<ShiDaoPKData> shiDaoPKData = shiDaoData.getPkDataByLevel().get(levelRange);
        List<Team> list = getFightTeamList(shiDaoPKData);
        List<Team> allList = getFightTeamList1(shiDaoPKData);
        log.error("匹配队伍数量=={}=={}",list.size(),levelRange);
        if (list.size()>0){
            match(allList, list);
        }
    }

    /**获得可以战斗的队伍*/
    private List<Team> getFightTeamList(List<ShiDaoPKData> pkList) {
        List<ShiDaoPKData> tempPkList = new ArrayList<>(pkList);
        tempPkList.sort(Comparator.comparing(ShiDaoPKData::getPrevPKTime));
        List<Team> list = new ArrayList<>(tempPkList.size());
        long now = System.currentTimeMillis();
        for (ShiDaoPKData shiDaoPKData : tempPkList) {
            Team team = teamService.getTeamByTeamId(shiDaoPKData.getTeamId());
            if (team == null) {continue;}

            Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
            if (leaderRole == null) {continue;}

            /**在战斗中，不加入列表*/
            if (fightService.canFight(leaderRole, team.getList()) == false) {continue;}

            /**能找到对应战斗对象时，不加入列表*/
            Fight fight = fightService.getFightByRoleId(leaderRole.getRoleId());
            if (fight != null) {continue;}

            /**没有对决值，不加入列表*/
//            if (shiDaoPKData.getPkValue() <= 0) {continue;}

            /**不在试道场，不加入列表*/
            if (leaderRole.getPos().getMapId() != Const.SHIDAO_MAPID) {continue;}

            /**当前时间-上次PK时间小于PK间隔时，不加入列表*/
            if (now - shiDaoPKData.getPrevPKTime() < PK_INTERVAL) {continue;}

            /**当前时间-上次PK时间小于PK间隔时，不加入列表*/
            if (now - leaderRole.getPrevFightEndTime() < PK_INTERVAL) {continue;}

            list.add(team);
        }
        return list;
    }


    /**
     * 所有在试道场中的队伍
     * @param pkList
     * @return
     */
    private List<Team> getFightTeamList1(List<ShiDaoPKData> pkList) {
        List<ShiDaoPKData> tempPkList = new ArrayList<>(pkList);
        tempPkList.sort(Comparator.comparing(ShiDaoPKData::getPrevPKTime));
        List<Team> list = new ArrayList<>(tempPkList.size());
        long now = System.currentTimeMillis();
        for (ShiDaoPKData shiDaoPKData : tempPkList) {
            Team team = teamService.getTeamByTeamId(shiDaoPKData.getTeamId());
            if (team == null) {continue;}

            Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
            if (leaderRole == null) {continue;}

            /**在战斗中，不加入列表*/
//            if (fightService.canFight(leaderRole, team.getList()) == false) {continue;}

            /**能找到对应战斗对象时，不加入列表*/
//            Fight fight = fightService.getFightByRoleId(leaderRole.getRoleId());
//            if (fight != null) {continue;}

            /**没有对决值，不加入列表*/
//            if (shiDaoPKData.getPkValue() <= 0) {continue;}

            /**不在试道场，不加入列表*/
            if (leaderRole.getPos().getMapId() != Const.SHIDAO_MAPID) {continue;}

            /**当前时间-上次PK时间小于PK间隔时，不加入列表*/
            if (now - shiDaoPKData.getPrevPKTime() < PK_INTERVAL) {continue;}

            /**当前时间-上次PK时间小于PK间隔时，不加入列表*/
            if (now - leaderRole.getPrevFightEndTime() < PK_INTERVAL) {continue;}

            list.add(team);
        }
        return list;
    }

    private void match(List<Team> allList, List<Team> list) {
        HashSet<Integer> hashSet = new HashSet<>();
        for (Team team:list){
            if (hashSet.contains(team.getId())){
                continue;
            }
            Team pkTeam = getPkTeam(team,allList, list,hashSet);
            if (pkTeam != null) {
                pkTeam.setLastTeamId(team.getId());
                team.setLastTeamId(pkTeam.getId());
                doStartFight(team, pkTeam);
                hashSet.add(team.getId());
                hashSet.add(pkTeam.getId());

                ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
                shiDaoData.getMatchTeamIds().put(team.getId(), pkTeam.getId());
                shiDaoData.getMatchTeamIds().put(pkTeam.getId(), team.getId());

                ShiDaoPKData shiDaoPKData = shiDaoData.getPkDataMap().get(team.getId());
                shiDaoPKData.updateTeamMember(team);

                shiDaoPKData = shiDaoData.getPkDataMap().get(pkTeam.getId());
                shiDaoPKData.updateTeamMember(pkTeam);

                log.info("试道大会巅峰对决匹配{} vs {}", team.getId(), pkTeam.getId());
            }
        }

    }

    private Team getPkTeam(Team team,List<Team> allList, List<Team> list, HashSet<Integer> hashSet) {
        /**列表剩余还有队伍时*/
        HashSet<Integer> teamHash = new HashSet<>();
        for (Member member : team.getList()){
            teamHash.add(member.getRoleId());
        }
        ArrayList<Team> result = new ArrayList<>();
        for (Team tempTeam : list){
            if (tempTeam.getId() == team.getId()){
                continue;
            }
            if (hashSet.contains(tempTeam.getId())){
                continue;
            }
            boolean boo = false;
            for (Member member : tempTeam.getList()){
                if (teamHash.contains(member.getRoleId())){
                    boo = true;
                    break;
                }
            }
            if (boo){
                continue;
            }
            result.add(tempTeam);
        }
        if (result.size() <=0){
            log.error("没有空闲的队伍=={}=={}",team.getId());
            return null;
        }

        if (allList.size() == 2){
            int index = new Random().nextInt(result.size());
            Team last = result.get(index);
            log.error("连续匹配同一个队伍=={}=={}",last.getId(),team.getId());
            return last;
        }else {
            ArrayList<Team> arrayList = new ArrayList<>();
            for (Team tempTeam:result){
                if (tempTeam.getId() == team.getLastTeamId()){
                    continue;
                }
                arrayList.add(tempTeam);
            }
            if (arrayList.size() <=0){
                log.error("没有匹配到队伍=={}=={}",team.getId());
                return null;
            }
            int index = new Random().nextInt(arrayList.size());
            Team last = arrayList.get(index);
            log.error("不连续匹配同一个队伍=={}=={}",last.getId(),team.getId());
            return last;
        }
//        if (list.size() > 0) {
//            /**列表中至少还剩余有两个队伍*/
//            if (list.size() > 1) {
//                /**把上次pk的队伍删除*/
//                ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
//                Integer prevPkTeamId = shiDaoData.getMatchTeamIds().get(team.getId());
//                if (prevPkTeamId != null) {list.remove(prevPkTeamId);}
//
//                if (list.size() > 1) {
//                    int index = ThreadLocalRandom.current().nextInt(list.size());
//                    return list.remove(index);
//                } else {
//                    return list.remove(0);
//                }
//            } else {
//                /**列表中只剩一个队伍时*/
//                return list.remove(0);
//            }
//        }
//
//        return null;
    }

    /**进行排名更新*/
    private void setRank(String levelRange) {
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        List<ShiDaoPKData> shiDaoPKDataList = shiDaoData.getPkDataByLevel().get(levelRange);
        if (shiDaoPKDataList == null){
            return;
        }
        Collections.sort(shiDaoPKDataList);

        byte rank = 0;
        for (ShiDaoPKData shiDaoPKData : shiDaoPKDataList) {
            rank += 1;
            shiDaoPKData.setRank(rank);
        }
    }

    public void doStartFight(Team teamA, Team teamB) {
        int mapId = Const.SHIDAO_MAPID;
        int fightType = getFightType();
        Fight fight = FightFactory.getFightFactory(fightType).create(mapId, getFightType(), teamA.getList(), teamB.getList());
        fight.setMaxRound(MAX_ROUND);
        fight.start();
    }

    protected int getFightType() {
//        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
//        if (shiDaoData != null && shiDaoData.isMonthTao()) {
//            return Const.fightType_month_shidao_pk;
//        }
        return Const.fightType_shidao_pk;
    }

    @Override
    public void handleFightEnd(FightEndEvent fightEndEvent) {
        /**事件应该是在战斗线程触发的，在玩家线程中处理玩家逻辑*/
        ThreadLocalUtil.addLocalTask(fightEndEvent.getRole(), () -> doFightEnd(fightEndEvent.getRole(), fightEndEvent));
    }

    public void doFightEnd(Role role, FightEndEvent fightEndEvent) {
        /**在组队又不是队长时返回*/
        if (teamService.isInTeam(role) && !teamService.isTeamLeader(role)) {
            return ;
        }

        if (!isMatchFightType(role, fightEndEvent.getFightType())) {
            return ;
        }
        if (role.getPos().getMapId() != Const.SHIDAO_MAPID) {
            return ;
        }

        /**更新组队情况*/
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        Team team = teamService.getTeam(role.getRoleId());
        if (team != null) {
            ShiDaoPKData shiDaoPKData = shiDaoData.getPkDataMap().get(team.getId());
            if (shiDaoPKData != null) {shiDaoPKData.updateTeamMember(team);}
        }

        if (fightEndEvent.getStatus() == FightEndEvent.WIN) {
            doFightWin(role, fightEndEvent);
        } else{
            doFightFail(role, fightEndEvent);
        }
//        if (fightEndEvent.getStatus() == FightEndEvent.FAIL) {
//            doFightFail(role, fightEndEvent);
//        } else if (fightEndEvent.getStatus() == FightEndEvent.RUNAWAY) {
//            doFightRunAway(role, fightEndEvent);
//        }
    }

    /**是否匹配战斗类型*/
    private boolean isMatchFightType(Role role, int fightType) {
        return getFightType() == fightType;
    }

    /**处理战斗胜利*/
    public void doFightWin(Role role, FightEndEvent fightEndEvent) {
        if (!isMatchFightType(role, fightEndEvent.getFightType())) {
            return ;
        }
        Team team = teamService.getTeam(role.getRoleId());
        addScore(role);
        setPrevPkTime(role);
        if (serverService.getServer().getId() == 10000){
            OneThreadService oneThreadService = SpringUtils.getBean(OneThreadService.class);
            ArrayList<Member> arrayList = new ArrayList<>(team.getList());
            for (Member member:arrayList){
                IoSession session = SessionUtils.getSession(member.getRoleId());
                if (session == null){
                    return;
                }
                Role tempRole = SessionUtils.getRoleBySession(session);
                if (tempRole == null){
                    continue;
                }
                oneThreadService.addFightTask(0, new Runnable() {
                    @Override
                    public void run() {
                        NutMap nutMap = new NutMap();
                        nutMap.put("name",tempRole.getName());
                        nutMap.put("type","道行");
                        nutMap.put("count",10);
                        NutMap param = new NutMap();
                        param.put("content",Json.toJson(nutMap,JsonFormat.compact()));
                        log.error("跨服试道胜利发放参与奖=11={}=={}=={}",tempRole.getRoleId(),tempRole.getName(),Json.toJson(nutMap,JsonFormat.compact()));
                        Request request = Request.create(serverService.getLoginServerUrl() + "/game/enterReward", Request.METHOD.GET).setParams(param);
                        Sender.create(request).setTimeout(2000).send().getContent();
                        log.error("跨服试道胜利发放参与奖=={}=={}=={}",tempRole.getRoleId(),tempRole.getName(),Json.toJson(nutMap,JsonFormat.compact()));
                    }
                });
                SpringUtils.getRoleService().addTotalTao11111(tempRole,10*Const.ONE_YEAR_DAY*Const.ONE_DAY_POINT);
                SpringUtils.getRoleService().addMonthTao11111(tempRole,10*Const.ONE_YEAR_DAY*Const.ONE_DAY_POINT);
            }
        }
        teamService.memberHandle(team, memberRole -> shiDaoHandler.sendRespShidaoScore(memberRole));
    }

    private void addScore(Role role) {
        /**增加试道积分*/
        Team team = teamService.getTeam(role.getRoleId());
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        ShiDaoPKData shiDaoPKData = shiDaoData.getPkDataMap().get(team.getId());
        if (shiDaoPKData != null) {
            short scorePkWin = shiDaoHandler.getShiDaoSet().getScorePkWin();
            shiDaoPKData.addTotalScore(scorePkWin);
            String msg = MessageFormat.format(WIN_MESSAGE, scorePkWin, shiDaoPKData.getTotalScore());
            teamService.pushMessageToTeam(team, new RespNotifyMiscEx(msg));

            log.info("{}({})增加试道积分：{}, 总积分: {}", team.getId(), team.getMemberNames(), scorePkWin, shiDaoPKData.getTotalScore());
        }
    }

    /**设置上次PK时间*/
    private void setPrevPkTime(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        ShiDaoPKData shiDaoPKData = shiDaoData.getPkDataMap().get(team.getId());
        if (shiDaoPKData != null) {
            shiDaoPKData.setPrevPKTime(System.currentTimeMillis());
        }
    }

    /**处理战斗失败*/
    public void doFightFail(Role role, FightEndEvent fightEndEvent) {
        fail(role, fightEndEvent);
    }

    /**处理战斗逃跑*/
    public void doFightRunAway(Role role, FightEndEvent fightEndEvent) {
        fail(role, fightEndEvent);
    }

    /**失败处理*/
    public void fail(Role role, FightEndEvent fightEndEvent) {
        Team team = teamService.getTeam(role.getRoleId());
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        ShiDaoPKData shiDaoPKData = shiDaoData.getPkDataMap().get(team.getId());
        if (shiDaoPKData != null) {
            /**减少对决值*/
            shiDaoPKData.substractPkValue((short) 1);
            // 减少积分
            shiDaoPKData.subTotalScore();
            String msg = MessageFormat.format(FAIL_MESSAGE, shiDaoPKData.getPkValue());
            teamService.pushMessageToTeam(team, new RespNotifyMiscEx(msg));
            log.info("{}({})减少对决值, 剩余对决值:{}", team.getId(), team.getMemberNames(), shiDaoPKData.getPkValue());
            if (serverService.getServer().getId() == 10000){
                OneThreadService oneThreadService = SpringUtils.getBean(OneThreadService.class);
                ArrayList<Member> arrayList = new ArrayList<>(team.getList());
                for (Member member:arrayList) {
                    IoSession session = SessionUtils.getSession(member.getRoleId());
                    if (session == null) {
                        return;
                    }
                    Role tempRole = SessionUtils.getRoleBySession(session);
                    if (tempRole == null) {
                        continue;
                    }
                    oneThreadService.addFightTask(0, new Runnable() {
                        @Override
                        public void run() {
                            NutMap nutMap = new NutMap();
                            nutMap.put("name",role.getName());
                            nutMap.put("type","道行");
                            nutMap.put("count",3);
                            NutMap param = new NutMap();
                            param.put("content",Json.toJson(nutMap,JsonFormat.compact()));
                            log.error("跨服试道失败发放参与奖=11={}=={}=={}",tempRole.getRoleId(),tempRole.getName(),Json.toJson(nutMap,JsonFormat.compact()));
                            Request request = Request.create(serverService.getLoginServerUrl() + "/game/enterReward", Request.METHOD.GET).setParams(param);
                            Sender.create(request).setTimeout(2000).send().getContent();
                            log.error("跨服试道失败发放参与奖=={}=={}=={}",tempRole.getRoleId(),tempRole.getName(),Json.toJson(nutMap,JsonFormat.compact()));
                        }
                    });
                    SpringUtils.getRoleService().addTotalTao11111(tempRole,3*Const.ONE_YEAR_DAY*Const.ONE_DAY_POINT);
                    SpringUtils.getRoleService().addMonthTao11111(tempRole,3*Const.ONE_YEAR_DAY*Const.ONE_DAY_POINT);
                }

            }

            /**对决值等于0 时，移出试道场*/
            if (shiDaoPKData.getPkValue() <= 0) {
                shiDaoHandler.leaveShiDaoMap(role);

                String levelRange = getLevelRange(shiDaoPKData);

                List<Integer> failTeamIds = shiDaoData.getFailTeamIds().computeIfAbsent(levelRange, k -> new ArrayList());
                failTeamIds.add(team.getId());

                String names = teamService.checkMember(team, memberRole -> memberRole != null);
                String outMsg = MessageFormat.format(OUT_MESSAGE, levelRange, names);
                SpringUtils.getChatService().sendSystem(outMsg, Const.BRODCAST_MSG_TYPE_ROLE);
            }
            teamService.memberHandle(team, memberRole -> shiDaoHandler.sendRespShidaoScore(memberRole));
        }

        setPrevPkTime(role);
    }

    private String getLevelRange(ShiDaoPKData shiDaoPKData) {
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        for(Map.Entry<String, List<ShiDaoPKData>> entry : shiDaoData.getPkDataByLevel().entrySet()) {
            if (entry.getValue().contains(shiDaoPKData)) {
                return entry.getKey();
            }
        }

        return null;
    }

    public void checkSystemMessage(Calendar calendar) {
        ShiDaoData shiDaoData = shiDaoHandler.getShiDaoData();
        Set<String> levelRanges = shiDaoData.getPkDataByLevel().keySet();

        for (String levelRange : levelRanges) {
            /**已经结束，跳过*/
            if (shiDaoData.getEndLevelRanges().contains(levelRange)) {continue;}

            /**22点后每5分钟发一次*/
            if (calendar.get(Calendar.HOUR_OF_DAY) == shiDaoData.getStartTime().get(Calendar.HOUR_OF_DAY) + 1 && calendar.get(Calendar.MINUTE) % 5 == 0) {
                int intevalMinute = getIntevalMinute(shiDaoData.getStartTime(), calendar);
                String msg = MessageFormat.format(USED_TIME_MESSAGE, levelRange, intevalMinute);
                SpringUtils.getChatService().sendSystem(msg, Const.BRODCAST_MSG_TYPE_ROLE);
            }
        }

        for (String levelRange : levelRanges) {
            /**已经结束，跳过*/
            if (shiDaoData.getEndLevelRanges().contains(levelRange)) {continue;}

            /**22点后每10分钟发一次*/
            if (calendar.get(Calendar.HOUR_OF_DAY) == shiDaoData.getStartTime().get(Calendar.HOUR_OF_DAY) + 1 && calendar.get(Calendar.MINUTE) % 10 == 0) {
                int intevalMinute = getIntevalMinute(calendar, shiDaoData.getEndTime());
                String msg = MessageFormat.format(REMAIN_TIME_MESSAGE, levelRange, intevalMinute);
                SpringUtils.getChatService().sendSystem(msg, Const.BRODCAST_MSG_TYPE_ROLE);
            }
        }
    }

    /**获得间隔分钟数*/
    private int getIntevalMinute(Calendar startCalendar, Calendar endCalendar) {
        return (int) Math.abs((endCalendar.getTimeInMillis() - startCalendar.getTimeInMillis()) / TimeUtil.ONE_MINUTE);
    }
}

